#include "link.h"
#include <QtSvg/QGraphicsSvgItem>
#include <QtGui/QPen>
#include <QtGui/QPainter>
#include <QtXml/QDomElement>

Link::Link(GActiveElement *startItem, GPool *endItem, 
			 const QString & portName, QGraphicsItem *parent)
	: QGraphicsPathItem(parent)
{
	mStartItem = startItem;
	mEndItem = endItem;
	//keep consistency
	mStartItem->addLink(this, portName);
	mEndItem->addLink(this);
	mStart = startItem->portFromName(portName);
	mDirection =  startItem->portDirection(mStart);
	setZValue(-1000);
	setFlag(QGraphicsItem::ItemIsSelectable, true);
}

Link::~Link()
{
	mStartItem->removeLink(this);
	mEndItem->removeLink(this);
}

QPainterPath Link::calPath(const QPointF p1, const QPointF p2, const QString direction)
{
	QPainterPath path;
	path.moveTo(p1);

	//identify the p2 is in which area of p1
	int area = 0;

	int factor = 1; //out
	qreal edgeV = 10;  //vertical border
	qreal border;
	qreal edgeH = 40;  //horizontal border
	qreal height = 30;
	//three zone of milestones
	qreal first = 10; 
	qreal second = 30;
	qreal third = 50;
	qreal x,y;
	
	//the area define how to draw the path.
	if (direction == "in") {
		factor = -factor;
		border = p1.x()-edgeV;
		if (border > p2.x()) area = 1;
	}else {
		border = p1.x()+edgeV;
		if (border < p2.x()) area = 1;
	}
	if (area == 0) {
		if ((p1.y()-edgeH > p2.y()) || (p1.y()+edgeH < p2.y())) 
			area = 2;
		else if (p1.y() > p2.y()) 
			area = 3;
		else
			area = 4;
	}

	y = p2.y();
	switch(area) {
	case 1: 
		path.lineTo( (p1.x()+p2.x())/2, p1.y());
		break;
	case 2: 
		x = p1.x() + third*factor + (p2.x()-border)/20;
		path.lineTo(x, p1.y());
		path.lineTo(x, p2.y());
		break;
	case 3: 
		y -= 2*height; //trick! in the next step, one width will be subtracted.
	case 4: 
		y += height;
	default: 
		x = p1.x() + second*factor + (p2.x()-border)/20;
		path.lineTo(x, p1.y());
		path.lineTo(x, y);
		path.lineTo(p2.x(), y);
	}

	path.lineTo(p2);
	return path;
}

void Link::updatePosition()
{
	if (scene()) {		
		QPointF origin = mapFromItem(mStart, mStart->boundingRect().center());
		QPointF end = mapFromItem(mEndItem, mEndItem->svgCenter());
		setPath(calPath(origin, end, mDirection));
	}
}

void Link::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
	if (!isSelected())
		painter->setPen(QPen(Qt::black, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
	else 
		painter->setPen(QPen(Qt::red, 2, Qt::DotLine, Qt::RoundCap, Qt::RoundJoin));
	painter->drawPath(path());
} 